/**
 * 
 */
package com.yufei.ui.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableModel;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.yufei.entity.Entity;
import com.yufei.utils.CommonUtil;
import com.yufei.utils.ExceptionUtil;



/**
 * @author zhaoyufei zhao-0244@qq.com
 * 
 *         created at 2012-9-5 下午3:23:39
 */
public class TableModelUtil {
	static Log mLog = LogFactory.getLog(TableModelUtil.class);

	/**
	 * 根据一个类来获取表格的model，列明对应着属性名
	 * 
	 * @param entity
	 * @return
	 */
	public static AbstractTableModel getTableModel(Class entity) {
		AbstractTableModel model = null;
		List<Field> fields = CommonUtil.getAllDeclareFields(entity);// entity.getDeclaredFields();
		// Field[] fields = entity.getFields();
		String[] columnNames = null;
		if (CommonUtil.isCustomerObjType(entity)) {
			columnNames = new String[fields.size()];
			int i = 0;
			for (Field field : fields) {
				columnNames[i] = field.getName();
				i++;
			}
			model = new javax.swing.table.DefaultTableModel(columnNames, 0);

		} else {
			columnNames = new String[1];
			columnNames[0] = "信息";
			model = new javax.swing.table.DefaultTableModel(columnNames, 0);
		}

		return model;

	}

	/**
	 * @param entity
	 * @param model
	 * @return
	 * @throws IllegalAccessException
	 * @throws InvocationTargetException
	 * @throws NoSuchMethodException
	 *             用于将带显示实体对象的属性值填充到具体的表格中
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 *             目前不支持Collection的嵌套，即entity的类型不能为Collection类型的，
	 *             但是可以为java基本类型以及customer obj changeLog:
	 *             再转化的过程中如果entity中的Collection类型或者customerObj为空的话将再次转换过程中将其生成一个实例
	 *             （确保collection 以及customerObj不能为null）
	 */
	public static Vector<Object> convertEntityToVector(Object entity,
			AbstractTableModel model) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException,
			SecurityException, NoSuchFieldException {
		Vector<Object> vector = new Vector<Object>();
		String property = null;
		Object columnValue = null;
		Class propertyType = null;
		// used to deal with the entity is Collection type
		if (!CommonUtil.isCustomerObjType(entity.getClass())
				&& !CommonUtil.isCollection(entity.getClass())) {

			vector.add(entity);
			return vector;
		}
		for (int i = 0; i < model.getColumnCount(); i++) {
			property = model.getColumnName(i);
			propertyType = PropertyUtils.getPropertyType(entity, property);
		
			columnValue = PropertyUtils.getProperty(entity, property);
			// collection or customer
			if (CommonUtil.isCollection(propertyType)
					|| CommonUtil.isCustomerObjType(propertyType)) {
				if (columnValue == null) {
					try {
						columnValue = propertyType.newInstance();
					} catch (InstantiationException e) {
						// TODO Auto-generated catch block
						mLog.info(ExceptionUtil.getExceptionDetailsMessage(e));
					}
				}

			}
			vector.add(columnValue);

		}
		// TODO Auto-generated method stub
		return vector;
	}

	public static List<Entity> convertVectorToEntity(Class entityClass,
			DefaultTableModel model) {
		List<Entity> entitys = new ArrayList<Entity>();
		Vector dataVector = model.getDataVector();
		Entity entity = null;
		String columnNames = null;

		for (Vector rowVector : (Vector<Vector>) dataVector) {
			try {
				entity = (Entity) entityClass.newInstance();
			} catch (InstantiationException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (IllegalAccessException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			int index = 0;
			String columnName = null;
			for (Object obj : rowVector) {
				columnName = convertTableValueToEntityProperty(model, entity,
						columnName, obj, index);

				index++;

			}
			entitys.add(entity);

		}
		return entitys;

	}

	public static Entity convertTableRowToEntity(Class entityClass,
			DefaultTableModel model, int rowNumber) {
		Entity entity = null;
		String columnNames = null;

		try {
			entity = (Entity) entityClass.newInstance();
		} catch (InstantiationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		String columnName = null;
		Object obj = null;
		int columnCount = model.getColumnCount();
		for (int column = 0; column < columnCount; column++) {
			obj = model.getValueAt(rowNumber, column);
			columnName = convertTableValueToEntityProperty(model, entity,
					columnName, obj, column);

		}

		return entity;

	}

	private static String convertTableValueToEntityProperty(
			DefaultTableModel model, Entity entity, String columnName,
			Object obj, int column) {
		try {
			columnName = model.getColumnName(column);
			// 如果obj为字符串类型而对应的表格中的类型不是string类型的时候需要进行手动转换
			Class propertyType = PropertyUtils.getPropertyType(entity,
					columnName);
			// 基本java数据类型比如：日期，Double,Long
			if (obj != null && !CommonUtil.isCustomerObjType(propertyType)) {
				// 目前仅仅支持Double,Integer类型与String 之间的转换
				if (CommonUtil.isCollection(propertyType)) {
					PropertyUtils.setProperty(entity, columnName, obj);

				} else {
					PropertyUtils.setProperty(entity, columnName,
							CommonUtil.objectConvert(propertyType, obj));

				}

			} else {
				// 自定义对象
				PropertyUtils.setProperty(entity, columnName,
						CommonUtil.objectConvert(propertyType, obj));

			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			mLog.debug("wrong when convert the Vector To Entity! the field name is   "
					+ columnName);
			mLog.debug(ExceptionUtil.getExceptionDetailsMessage(e));
		}
		return columnName;
	}
}
